#define STB_IMAGE_IMPLEMENTATION
#include "texture.hpp"
#include "lib/stb_image.h"
#include "GL/glut.h"
#include <iostream>

using namespace std;

void TextureManager::registerTexture(const char *filename, string texname) {
    unsigned id;
    int width, height, channel;
    unsigned char *image;

    if (tex_set.find(texname) != tex_set.end()) {
        cout << "Texture: " << texname
            << "is already registered. Please change a name" << endl;
        return;
    }
    // genterate texture id
    glGenTextures(1, &id);

    image = stbi_load(filename, &width, &height, &channel, 0);

    if (image != NULL) {
        // set some parameter for the texture
        glBindTexture(GL_TEXTURE_2D, id);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        GLuint format;
        if (channel == 1)
            format = GL_RED;
        else if (channel == 3)
            format = GL_RGB;
        else if (channel == 4)
            format = GL_RGBA;
		else format = GL_RGB;
        // cout << channel << endl;
        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
                    GL_UNSIGNED_BYTE, image);
        tex_set[texname] = id;
        // cout << id << endl;
    } else {
        cout << "Registeration fail." << endl;
    }

    stbi_image_free(image);
}

unsigned TextureManager::getTextureId(string texname) {
    if (tex_set.find(texname) == tex_set.end()) {
        cout << "Texture: " << texname << " doesn't exist." << endl;
        return 0;
    } else
        return tex_set[texname];
}

// Usage:
// glActiveTexture(GL_TEXTURE0);
// bindTexture(texname);
void TextureManager::bindTexture(string texname) {
    if (tex_set.find(texname) == tex_set.end()) {
        cout << "Texture: " << texname << " doesn't exist." << endl;
    } else
        glBindTexture(GL_TEXTURE_2D, tex_set[texname]);
}

vector<string> TextureManager::getTexnameList() {
    vector<string> texname_list;
    for (map<string, unsigned>::iterator it = tex_set.begin();
        it != tex_set.end(); ++it) {
        texname_list.push_back(it->first);
    }
    return texname_list;
}
